﻿// Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
//
// This file is part of SharpMap.
// SharpMap is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// SharpMap is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public License
// along with SharpMap; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 

using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Text;

namespace Petra.Gis.ReferenceSystemServices
{
  /// <summary>
  /// The Projection class defines the standard information stored with a projection
  /// objects. A projection object implements a coordinate transformation from a geographic
  /// coordinate system to a projected coordinate system, given the ellipsoid for the
  /// geographic coordinate system. It is expected that each coordinate transformation of
  /// interest, e.g., Transverse Mercator, Lambert, will be implemented as a class of
  /// type Projection, supporting the IProjection interface.
  /// </summary>
  [DataContract(Name="PROJECTION")]
  public class ProjectionDefinition
  {

    /// <summary>
    /// xaml constr.
    /// </summary>
    public ProjectionDefinition() 
    {
      Parameters = new TransformParameters();
    }




    public ProjectionDefinition(string className, TransformParameters parameters,
      Metadata metadata/*, bool isRegularOrthogonal*/)
    {
      Metadata = metadata;
      Parameters = parameters;
      ClassName = className;
      //_isRegularOrthogonal = isRegularOrthogonal;
    }


    #region Projection Members



    //protected TransformParameters _parameters;

    /// <summary>
    /// Gets or sets the parameters of the projection
    /// </summary>
    [DataMember(Name="PARAMS", Order = 2)]
    public TransformParameters Parameters
    { get; set; }






    //protected DistanceUnit _distanceParamUnit;

    /// <summary>
    /// get/set correct unit for all distance type projection parameters
    /// projection usually contains mix of parameters
    /// in either none, distance or angular untis
    /// </summary>
    [DataMember(Name = "PARAM_DIST_UNIT")]
    public DistanceUnit DistanceParameterUnit
    { get; set; }






    //protected AngularUnit _angularParamUnit;

    /// <summary>
    /// get/set correct unit for all distance type projection parameters
    /// projection usually contains mix of parameters
    /// in either none, distance or angular untis
    /// </summary>
    [DataMember(Name = "PARAM_ANGULAR_UNIT")]
    public AngularUnit AngularParameterUnit
    { get; set; }






    //protected Metadata _metadata;

    /// <summary>
    /// get or set projection metadata
    /// </summary>
    [DataMember(Name="INFO", Order = 3)]
    public Metadata Metadata
    { get; set; }




    //private string _className;

    /// <summary>
    /// Gets the projection classification name (e.g. "Transverse_Mercator").
    /// </summary>
    [DataMember(Name="NAME", Order = 1)]
    public string ClassName
    { get; set; }



    /// <summary>
    /// Checks whether the values of this instance is equal to the values of another instance.
    /// Only parameters used for coordinate system are used for comparison.
    /// Name, abbreviation, authority, alias and remarks are ignored in the comparison.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns>True if equal</returns>
    public bool EqualParams(object obj)
    {
      if (!(obj is ProjectionDefinition))
        return false;

      ProjectionDefinition proj = obj as ProjectionDefinition;
      if (proj.Parameters.Count != this.Parameters.Count)
        return false;

      foreach (KeyValuePair<string, double>param in this.Parameters)
      {
        if (!proj.Parameters.ContainsKey(param.Key))
          return false;
        else if (param.Value != proj.Parameters[param.Key])
          return false;
      }
      return true;
    }

    #endregion

  }
}
